#pragma once

#include <strstream>

namespace grazier
{

class IEventData;

typedef unsigned long EventType;
typedef shared_ptr<IEventData> IEventDataPtr;
typedef fastdelegate::FastDelegate1<IEventDataPtr> EventListenerDelegate;

class IEventData
{
public:
	virtual const EventType& VGetEventType(void) const = 0;
	virtual float GetTimeStamp(void) const = 0;
	virtual void VSerialize(std::ostrstream& out) const = 0;
	virtual void VDeserialize(std::istrstream& in) = 0;
	virtual IEventDataPtr VCopy(void) const = 0;
	virtual const char* GetName(void) const = 0;

};

class BaseEventData : public IEventData
{
	const float m_timeStamp;

public:
	explicit BaseEventData(const float timeStamp = 0.0f) : m_timeStamp(timeStamp) {}
	virtual ~BaseEventData(void) {}

	virtual const EventType& VGetEventType(void) const =0;

	float GetTimeStamp(void) const { return m_timeStamp; }

	// Serializing for network input / output
	virtual void VSerialize(std::ostrstream &out) const	{ }
	virtual void VDeserialize(std::istrstream& in) { }
};

class IEventManager
{
	enum eConstants { kINFINITE = 0xffffffff };

	IEventManager(void);
	virtual ~IEventManager(void);

	virtual bool VAddListener(const EventListenerDelegate& eventDelegate, const EventType type) = 0;

	virtual bool VRemoveListener(const EventListenerDelegate& eventDelegate, const EventType& type) = 0;

	virtual bool VTriggerEvent(const IEventDataPtr& pEvent) const = 0;

	virtual bool VQueueEvent(const IEventDataPtr& pEvent) = 0;
	
	virtual bool VAbortEvent(const EventType& type, bool allOfType = false) = 0;

	virtual bool VUpdate(unsigned int maxMillis = kINFINITE) = 0;
};

} //namespace grazier